package alingrad.engine.src.util;

import java.util.PriorityQueue;

import alingrad.engine.src.graphics.Renderable;

/**
 * A Priority Queue which queues {@link Renderable}s in order of draw order.
 * @author alingrad
 *
 */
public class RenderQueue {
	/**
	 * Priority Queue
	 */
	private PriorityQueue<RenderQueueNode> queue;

	/**
	 * Constructs a new empty RenderQueue.
	 */
	public RenderQueue() {
		queue = new PriorityQueue<RenderQueueNode>();
	}

	/**
	 * A node in the RenderQueue
	 * @author alingrad
	 *
	 */
	private class RenderQueueNode implements Comparable<RenderQueueNode> {
		/**
		 * The priority of the node.
		 */
		private int priority;
		/**
		 * The data within the node.
		 */
		private Renderable node;

		/**
		 * Constructs a new RenderQueueNode.
		 * @param node the data.
		 * @param priority the priority of the node.
		 */
		public RenderQueueNode(Renderable node, int priority) {
			this.node = node;
			this.priority = priority;
		}

		@Override
		public int compareTo(RenderQueueNode o) {
			return priority - o.priority;
		}

		/**
		 * Gets the data within the node.
		 * @return the data.
		 */
		public Renderable getNode() {
			return node;
		}
	}

	/**
	 * Add a {@link Renderable} into the queue.
	 * @param node the data.
	 * @param drawOrder the order to draw.
	 * @return the success of adding the {@link Renderable}
	 */
	public boolean add(Renderable node, int drawOrder) {
		return queue.add(new RenderQueueNode(node, drawOrder));
	}

	/**
	 * Removes the next object to draw in the queue.
	 * @return the object to draw.
	 */
	public Renderable remove() {
		return queue.poll().getNode();
	}

	/**
	 * Returns if the Queue is empty.
	 * @return whether the queue is empty.
	 */
	public boolean isEmpty() {
		return queue.isEmpty();
	}
}
